<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   
      <title>4.3. Tratamiento de ficheros</title>
      <meta name="generator" content="DocBook XSL-NS Stylesheets V1.75.2">
      <link rel="home" href="indice.html" title="Manual Usuario gvHidra">
      <link rel="up" href="ch04.html" title="Cap&iacute;tulo 4. Elementos de pantalla avanzados">
      <link rel="prev" href="ch04s02.html" title="4.2. Componentes complejos">
      <link rel="next" href="ch04s04.html" title="4.4. Control de la Navegaci&oacute;n. Saltando entre ventanas">
   </head>
   <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
      <div class="navheader">
         <table width="100%" summary="Navigation header">
            <tr>
               <th colspan="3" align="center">4.3. Tratamiento de ficheros</th>
            </tr>
            <tr>
               <td width="20%" align="left"><a accesskey="p" href="ch04s02.html">Anterior</a>&nbsp;
               </td>
               <th width="60%" align="center">Cap&iacute;tulo 4. Elementos de pantalla avanzados</th>
               <td width="20%" align="right">&nbsp;<a accesskey="n" href="ch04s04.html">Siguiente</a></td>
            </tr>
         </table>
         <hr>
      </div>
      <div class="section" title="4.3. Tratamiento de ficheros">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title" style="clear: both"><a name="d4e3730"></a>4.3. Tratamiento de ficheros
                  </h2>
               </div>
            </div>
         </div>
             
         
             
         <p>Vamos a contar como trabajar con documentos y ficheros de cualquier
            tipo. A&ntilde;adimos ejemplos de como insertar un fichero en la BD, como mostrar
                una imagen que se encuentra en el servidor en un campo CWImagen, como
                insertar N tuplas en una BD a partir de un fichero XML.
         </p>
         
             
         <div class="section" title="4.3.1. Manejo de ficheros de im&aacute;genes">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a name="d4e3733"></a>4.3.1. Manejo de ficheros de im&aacute;genes
                     </h3>
                  </div>
               </div>
            </div>
                  
            
                  
            <p>En este primer ejemplo vamos a mostrar como crear un mantenimiento
                     que almacene im&aacute;genes en la BD (en nuestro ejemplo PostgreSQL) y las
                     muestre en un <span class="bold"><strong>CWImagen</strong></span>. Para conseguir
                     esto necesitamos que en la interfaz (en la tpl) aparezcan dos plugins
                     especiales de tratamiento de ficheros (<span class="bold"><strong>CWUpLoad</strong></span> y el <span class="bold"><strong>CWImagen</strong></span>).
            </p>
            
                  
            <p>El primero de ellos, el <span class="bold"><strong>CWUpLoad</strong></span>,
                     nos permite seleccionar un fichero ubicado en el ordenador cliente y
                     subirlo al servidor Web. El contenido de este fichero se almacena en una
                     ubicaci&oacute;n temporal y el programador es el encargado de hacer uso de &eacute;l.
                     Posteriormente mostraremos los m&eacute;todos que gvHidra proporciona para que
                     se tenga acceso a la informaci&oacute;n de dicho fichero.
            </p>
            
                  
            <p>El segundo de ellos es el <span class="bold"><strong>CWImagen</strong></span>, que permite mostrar una imagen en un
                     panel a partir de una URL.
            </p>
            
                  
            <p>A continuaci&oacute;n mostramos un ejemplo del panel resultado:</p>
            
                  
            <div class="mediaobject"><img src="images/imagenes.jpeg"></div>
            
                  
            <p>Para conseguir esto tenemos que tener en cuenta las dos partes que
                     van a suponer trabajo para el programador, por un lado el tratamiento
                     del fichero imagen cuando el usuario lo selecciona con el <span class="bold"><strong>CWUpLoad</strong></span> y lo quiere almacenar en el servidor y,
                     por otro, la representaci&oacute;n de un fichero imagen en el <span class="bold"><strong>CWImagen</strong></span>. El primero de estos pasos necesita de
                     un acceso a la informaci&oacute;n del fichero y la inserci&oacute;n del mismo en la
                     tupla que se est&eacute; modificando. A continuaci&oacute;n mostramos el c&oacute;digo que se
                     ha insertado en el panel para resolverlo.
            </p>
            
                  
            <div class="informalexample">
                       
               
                       <pre class="programlisting">public function postModificar($objDatos) 
{
    do
    {
      $datosFile = $objDatos-&gt;<span class="bold"><strong>getFileInfo</strong></span>('ficheroUpload');
      if(is_array($datosFile) and ($datosFile['tmp_name']!='')){
        $fichero = <span class="bold"><strong>pg_escape_bytea</strong></span>(<span class="bold"><strong>file_get_contents</strong></span>($datosFile['tmp_name']));
        $res = $this-&gt;operar("update tinv_imagenes SET fichero='{$fichero}', nombre='".$datosFile['name']."' where id=".$objDatos-&gt;getValue('id'));
        if($res==-1)
        {
          $this-&gt;showMensaje('APL-25');
          return -1;
        }
      }      
    } while($objDatos-&gt;nextTupla());  
    return 0;
  }</pre>
                     </div>
            
                  
            <p>De este c&oacute;digo destaca, en primer lugar, el m&eacute;todo <span class="bold"><strong>getFileInfo()</strong></span> del objeto objDatos. Este m&eacute;todo
                     devuelve el array de informaci&oacute;n del HTTP que indica los datos del
                     fichero que ha subido el usuario (nombre, tipo, ubicaci&oacute;n,...). A partir
                     de esta informaci&oacute;n el programador ya puede hacer uso del fichero; y, en
                     este caso, decide insertarlo en una BD PostgreSQL. Para ello va a hacer
                     uso de un campo de tipo Bytea y, por esta raz&oacute;n, utiliza las siguientes
                     premisas. Primero, tras obtener el contenido del fichero (funci&oacute;n php
                     <span class="emphasis"><em>file_get_contents</em></span>) utiliza la funci&oacute;n nativa de php
                     <span class="emphasis"><em>pg_escape_bytea</em></span> para poder construir la consulta.
                     Construye la consulta incluyendo el contenido (escapado) del fichero
                     entre llaves. De este modo la instrucci&oacute;n no tiene problemas al pasar el
                     array de bytes al PosgreSQL. El otro punto complejo de esta pantalla
                     est&aacute; en la recuperaci&oacute;n de la imagen de la BD. Para ello debemos obtener
                     la imagen del campo bytea y almacenarla en una ubicaci&oacute;n accesible por
                     nuestro plugin <span class="bold"><strong>CWImagen</strong></span>. Por esta
                     raz&oacute;n, en este caso hemos decidido crear un directorio imagenes en la
                     raiz de nuestro proyecto (tambi&eacute;n se podria usar el templates_c que ya
                     usamos para smarty) donde se crear&aacute;n los ficheros que se quieran
                     visualizar. Luego se asignar&aacute; al <span class="bold"><strong>CWImagen</strong></span> la ruta de cada uno de ellos. El c&oacute;digo
                     que se encarga de realizar esto es:
            </p>
            
                  
            <div class="informalexample">
                       
               
                       <pre class="programlisting">public function postEditar($objDatos) 
{
    //Comprobamos si tiene imagen y en este caso la cargamos.
    $res = $objDatos-&gt;getAllTuplas();
    foreach($res as $indice =&gt; $tupla)
    {
      if($tupla['fichero']!='')
      {
        $nuevoFichero = "imagenes/".$tupla['nombre'];
        if(!file_exists($nuevoFichero))
        {
          $imagen = pg_unescape_bytea($tupla['fichero']);
          $gestor = fopen($nuevoFichero, 'x');
          fwrite($gestor,$imagen);
        }
        $res[$indice]['fichero'] = $nuevoFichero;
      }
    }
    $objDatos-&gt;setAllTuplas($res);
}//Function postEditar</pre>
                     </div>
            
                  
            <p>Como se puede suponer del c&oacute;digo anterior, el CWImagen se llama
                     fichero.
            </p>
            
                  
            <div class="informalexample">
                       
               
                       <pre class="programlisting">{CWImagen nombre="fichero"}
{CWUpLoad nombre="ficheroUpload" size="10" textoAsociado="Si quieres cambiar la imagen..."}</pre>
                     </div>
                
         </div>
         
             
         <div class="section" title="4.3.2. Manejo de ficheros de cualquier tipo">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a name="d4e3766"></a>4.3.2. Manejo de ficheros de cualquier tipo
                     </h3>
                  </div>
               </div>
            </div>
                  
            
                  
            <p>Puede darse el caso que queramos almacenar documentos de cualquier
                     tipo en la BD. Para ello tendr&iacute;amos que hacer una simple modificaci&oacute;n al
                     c&oacute;digo anterior. Es evidente que ya no nocesitariamos el plugin
                     CWImagen. Lo &uacute;nico que necesitamos es un bot&oacute;n que lance una acci&oacute;n
                     particular que recupera el documento de la BD y lance el mismo a una
                     nueva ventana del navegador. El c&oacute;digo que se encarga de realizar esto
                     es el siguiente
            </p>
            
                  
            <div class="informalexample">
                       
               
                       <pre class="programlisting">public function accionesParticulares($str_accion, $objDatos) 
{
    switch ($str_accion) 
    {
      case 'verFichero':
        //Bucle para crear un listado para cada peticion seleccionada:
        $objDatos-&gt;setOperacion("seleccionar");
        $m_datosSeleccionados = $objDatos-&gt;getAllTuplas();
        $res = $this-&gt;consultar("SELECT fichero,tipo from tinv_documentos WHERE id = ".$m_datosSeleccionados[0]['id']);
        if($res[0]['fichero']!='')
        {
          header('Content-Type: '.$res[0]['tipo']);
          header('Content-Disposition: attachment; filename="'.$m_datosSeleccionados[0]['nombre'].'"');
          print(pg_unescape_bytea($res[0]['fichero']));
          ob_end_flush ();
          //Para que no continue la ejecuci&oacute;n de la p&aacute;gina
          die;        
        }   
        $actionForward = $objDatos-&gt;getForward('correcto');
       break;
    }
    return $actionForward;          
}  </pre>
                     </div>
            
                  
            <p>Como nota podemos indicar que, a diferencia del ejemplo anterior,
                     en este ejemplo, al almacenar el documento en la BD se almacena no s&oacute;lo
                     su contenido, sino tambi&eacute;n el tipo. De este modo se puede asignar al
                     header para que el navegador lo abra con el programa adecuado para
                     tratarlo dependiendo de la extensi&oacute;n (MIME-TYPES).
            </p>
                
         </div>
         
             
         <div class="section" title="4.3.3. Importar datos a la BD desde fichero">
            <div class="titlepage">
               <div>
                  <div>
                     <h3 class="title"><a name="d4e3772"></a>4.3.3. Importar datos a la BD desde fichero
                     </h3>
                  </div>
               </div>
            </div>
                  
            
                  
            <p>Este es otro de los ejemplos t&iacute;picos con los que nos podemos
                     encontrar. Imaginemos el caso de una aplicaci&oacute;n que carga sus datos a
                     partir de una fuente externa como, por ejemplo, un XML. Para este
                     ejemplo s&oacute;lo utilizaremos el plugin CWUpLoad y el c&oacute;digo ser&iacute;a el
                     siguiente:
            </p>
            
                  
            <div class="informalexample">
                       
               
                       <pre class="programlisting">public function accionesParticulares($str_accion, $objDatos) 
{
    switch ($str_accion) 
    {
      case 'importarFichero':
        $objDatos-&gt;setOperacion('external');
        $datosFile = $objDatos-&gt;getFileInfo('ficheroUpload');
        $contenidoFichero = utf8_encode(file_get_contents($datosFile['tmp_name']));
        $dom = domxml_open_mem($contenidoFichero,
          DOMXML_LOAD_PARSING + //0
          DOMXML_LOAD_COMPLETE_ATTRS + //8
          DOMXML_LOAD_SUBSTITUTE_ENTITIES + //4
          DOMXML_LOAD_DONT_KEEP_BLANKS //16 
        );
        if(is_object($dom))
        {
          $xpathXML = $dom-&gt;xpath_new_context();
          $xpresultXML = $xpathXML-&gt;xpath_eval("//persona", $xpathXML);
          $v_personas = $xpresultXML-&gt;nodeset;
          //preparamos los contadores
          $insertados = 0;
          $totales = 0;
          foreach($v_personas as $persona)
          {
            $nif = $persona-&gt;get_attribute('nif');
            $comprobacion = $this-&gt;consultar('SELECT count(1) as "cuenta" FROM tinv_xml where nif=\''.$nif.'\'');
            if($comprobacion[0]["cuenta"]==0)
            {
              $nombre = $persona-&gt;get_attribute('nombre');
              $apellidos = $persona-&gt;get_attribute('apellidos');
              $correcto = $this-&gt;operar("INSERT INTO tinv_xml values ('".$nif."','".$nombre."','".$apellidos."')");
              if($correcto!=-1)
                $insertados++;
            }
            $totales++;
          }
          $this-&gt;showMensaje('APL-26',array($insertados,$totales));
        }
        else {
          $this-&gt;showMensaje('APL-27');
        }
        $this-&gt;setResultadoBusqueda(array());
        $actionForward = $objDatos-&gt;getForward('correcto');
        break;
      default:
        die("La acci&oacute;n $str_accion no est&aacute; activada para esta clase.");
    }
    return $actionForward;
  }</pre>
                     </div>
            
                  
            <p>Como podemos ver, la aplicaci&oacute;n espera un fichero XML del que
                     extrae todos los tags &lt;persona&gt;. Si no existen en la BD los
                     inserta con los atributos deseados.
            </p>
                
         </div>
           
      </div>
      <div class="navfooter">
         <hr>
         <table width="100%" summary="Navigation footer">
            <tr>
               <td width="40%" align="left"><a accesskey="p" href="ch04s02.html">Anterior</a>&nbsp;
               </td>
               <td width="20%" align="center"><a accesskey="u" href="ch04.html">Subir</a></td>
               <td width="40%" align="right">&nbsp;<a accesskey="n" href="ch04s04.html">Siguiente</a></td>
            </tr>
            <tr>
               <td width="40%" align="left" valign="top">4.2. Componentes complejos&nbsp;</td>
               <td width="20%" align="center"><a accesskey="h" href="indice.html">Inicio</a></td>
               <td width="40%" align="right" valign="top">&nbsp;4.4. Control de la Navegaci&oacute;n. Saltando entre ventanas</td>
            </tr>
         </table>
      </div>
   </body>
</html>